package intellij.haskell.cabal.lang.psi

import com.intellij.lang.ASTNode
import intellij.haskell.cabal.lang.psi.CabalTypes._

object CabalElementFactory {
  def createElement(node: ASTNode): CabalCompositeElement = node.getElementType match {
    case INVALID_FIELD => new InvalidField(node)
    case UNKNOWN_FIELD => new UnknownField(node)
    case CUSTOM_FIELD => new CustomField(node)
    case PKG_NAME => new PkgName(node)
    case PKG_VERSION => new PkgVersion(node)
    case CABAL_VERSION => new CabalVersion(node)
    case BUILD_TYPE => new BuildType(node)
    case LICENSE => new License(node)
    case LICENSE_FILE => new LicenseFile(node)
    case LICENSE_FILES => new LicenseFiles(node)
    case COPYRIGHT => new Copyright(node)
    case AUTHOR => new Author(node)
    case MAINTAINER => new Maintainer(node)
    case STABILITY => new Stability(node)
    case HOMEPAGE => new Homepage(node)
    case BUG_REPORTS => new BugReports(node)
    case PACKAGE_URL => new PackageUrl(node)
    case SYNOPSIS => new Synopsis(node)
    case DESCRIPTION => new Description(node)
    case CATEGORY => new Category(node)
    case TESTED_WITH => new TestedWith(node)
    case DATA_FILES => new DataFiles(node)
    case DATA_DIR => new DataDir(node)
    case EXTRA_SOURCE_FILES => new ExtraSourceFiles(node)
    case EXTRA_DOC_FILES => new ExtraDocFiles(node)
    case EXTRA_TMP_FILES => new ExtraTmpFiles(node)
    case MAIN_IS => new MainIs(node)
    case BUILD_DEPENDS => new BuildDepends(node)
    case DEPENDENCIES => new Dependencies(node)
    case DEPENDENCY => new Dependency(node)
    case DEPENDENCY_VERSION => new DependencyVersion(node)
    case THIN_RENAME_MODULES => new ThinRenameModules(node)
    case WITH_RENAME_MODULES => new WithRenameModules(node)
    case RENAME_MODULE => new RenameModule(node)
    case OTHER_MODULES => new OtherModules(node)
    case DEFAULT_LANGUAGE => new DefaultLanguage(node)
    case OTHER_LANGUAGES => new OtherLanguages(node)
    case DEFAULT_EXTENSIONS => new DefaultExtensions(node)
    case OTHER_EXTENSIONS => new OtherExtensions(node)
    case HS_SOURCE_DIR => new HsSourceDir(node)
    case HS_SOURCE_DIRS => new HsSourceDirs(node)
    case EXTENSIONS => new Extensions(node)
    case BUILD_TOOLS => new BuildTools(node)
    case BUILDABLE => new Buildable(node)
    case GHC_OPTIONS => new GhcOptions(node)
    case GHC_PROF_OPTIONS => new GhcProfOptions(node)
    case GHC_SHARED_OPTIONS => new GhcSharedOptions(node)
    case INCLUDES => new Includes(node)
    case INSTALL_INCLUDES => new InstallIncludes(node)
    case INCLUDE_DIRS => new IncludeDirs(node)
    case C_SOURCES => new CSources(node)
    case JS_SOURCES => new JsSources(node)
    case EXTRA_LIBRARIES => new ExtraLibraries(node)
    case EXTRA_GHCI_LIBRARIES => new ExtraGhciLibraries(node)
    case EXTRA_LIB_DIRS => new ExtraLibDirs(node)
    case CC_OPTIONS => new CcOptions(node)
    case CPP_OPTIONS => new CppOptions(node)
    case LD_OPTIONS => new LdOptions(node)
    case PKGCONFIG_DEPENDS => new PkgconfigDepends(node)
    case FRAMEWORKS => new Frameworks(node)
    case REQUIRED_SIGNATURES => new RequiredSignatures(node)

    case SOURCE_REPO => new SourceRepo(node)
    case SOURCE_REPO_TYPE => new SourceRepoType(node)
    case SOURCE_REPO_LOCATION => new SourceRepoLocation(node)
    case SOURCE_REPO_MODULE => new SourceRepoModule(node)
    case SOURCE_REPO_BRANCH => new SourceRepoBranch(node)
    case SOURCE_REPO_TAG => new SourceRepoTag(node)
    case SOURCE_REPO_SUBDIR => new SourceRepoSubdir(node)

    case FLAG_DECL => new FlagDecl(node)
    case FLAG_DESCR => new FlagDescr(node)
    case FLAG_DEFAULT => new FlagDefault(node)
    case FLAG_MANUAL => new FlagManual(node)

    case LIBRARY => new Library(node)
    case EXPOSED_MODULES => new ExposedModules(node)
    case EXPOSED => new Exposed(node)
    case REEXPORTED_MODULES => new ReexportedModules(node)
    case MODULE_REEXPORT => new ModuleReexport(node)

    case EXECUTABLE => new Executable(node)

    case TEST_SUITE => new TestSuite(node)
    case TEST_SUITE_TYPE => new TestSuiteType(node)

    case BENCHMARK => new Benchmark(node)
    case BENCHMARK_TYPE => new BenchmarkType(node)

    case INVALID_STANZA => new InvalidStanza(node)

    case FREEFORM => new Freeform(node)
    case IDENT_LIST => new IdentList(node)
    case MODULE_LIST => new ModuleList(node)
    case MODULE => new Module(node)
    case MODULE_PART => new ModulePart(node)
    case BOOL_VALUE => new BoolValue(node)

    case FUNC_CALL => new FuncCall(node)
    case FUNC_NAME => new FuncName(node)
    case FUNC_ARG => new FuncArg(node)

    case IF_EXPR => new IfExpr(node)
    case IF_COND => new IfCond(node)
    case THEN_BODY => new ThenBody(node)
    case ELSE_BODY => new ElseBody(node)
    case LOGICAL_NEG => new LogicalNeg(node)
    case BOOL_LIT => new BoolValue(node)

    case other => throw new AssertionError("Unexpected element type: " + other)
  }
}
